package net.entelijan.cobean.examples.lit;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import net.entelijan.cobean.worker.CobeanWorker;
import net.entelijan.cobean.worker.InternalTaskCompanionAdapter;
import net.entelijan.cobean.worker.api.ITaskCompanion;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public abstract class DefaultActionListener implements ActionListener {

	private static Log log = LogFactory.getLog(DefaultActionListener.class);

	private String actionName;

	public DefaultActionListener(String actionName) {
		super();
		this.actionName = actionName;
	}

	@Override
	public void actionPerformed(final ActionEvent e) {
		final CobeanWorker<Void> worker = new CobeanWorker<Void>() {

			protected Void doInBackground(ITaskCompanion companion)
					throws Exception {
				actionPerformedIntern(e);
				return null;
			}

		};
		InternalTaskCompanionAdapter<Void> companion = new InternalTaskCompanionAdapter<Void>() {

			@Override
			public void setException(Exception ex) {
				String msgIntern = "Could not '" + actionName + "' because: "
						+ ex.getMessage();
				String msgExtern = "Could not '" + actionName + "' because: "
						+ getExternMessage(ex);
				if (log.isDebugEnabled()) {
					log.error(msgIntern, ex);
				} else {
					log.error(msgIntern);
				}
				JOptionPane.showMessageDialog(SwingUtilities
						.getRoot((Component) e.getSource()), StringUtils
						.abbreviate(msgExtern, 100));
			}

			private String getExternMessage(Exception ex) {
				String re;
				if (containsCause(ex, java.net.ConnectException.class)) {
					re = "Could not connect to server";
				} else if (containsCause(ex, javax.persistence.PersistenceException.class)) {
					re = ex.getMessage();
				} else {
					re = "Technical problems";
				}
				return re;
			}

			private boolean containsCause(Throwable ex,
					Class<? extends Exception> clazz) {
				if (ex.getClass().equals(clazz)) {
					return true;
				} else if (ex.getCause() == null) {
					return false;
				} else {
					return containsCause(ex.getCause(), clazz);
				}
			}

		};
		worker.execute(companion);
	}

	protected abstract void actionPerformedIntern(ActionEvent e)
			throws Exception;

}
